perm filename OBJFTP.SAI[11,HE] blob sn#651176 filedate 1982-04-01 generic text, type T, neo UTF8
BEGIN "FTP Program Image mode only 10→11"	comment OBJFTP.SAI;

COMMENT For variable-length files such as .OBJ files, which have been read
	from tape using COPY, where the tape is in industry-compatible mode
	(ANSI-labelled format).
	It changes the ASCII record length which appears at the beginning
	of each record into what RSX wants, which is a single word record
	length indicator.  Other than that, just like IFTP.SAI;

DEFINE	CRLF="('15&'12)",
	CR  ="'15",
	LF  ="'12",
	! = "COMMENT ",
	TIL="STEP 1 UNTIL";

REQUIRE "11UTIL.HDR[11,SYS]" SOURCE_FILE;

DEFINE TTYSET = "'047000400121";
DEFINE GETLIN = "'051300000000";

INTEGER chan;  !  Channel number for I/O to RSX;
INTEGER dskchan;  !  Channel number for 10 disk I/O;
EXTERNAL INTEGER _SKIP_;

INTEGER ARRAY inbuffer[1:256], outbuffer[1:256];
INTEGER endbuf;
INTEGER talk10,char,i,j,k,l,brk,dum,eof,base,bufadr,bufptr;
INTEGER outptr, inptr;
STRING s,f1,fnam10,fext10,ppn10;
LABEL fin;


PROCEDURE parse10 (STRING s);
  BEGIN
  fnam10 ← fext10 ← NULL;
  WHILE s=" " ∧ s ≠ NULL DO dum ← LOP(s);	! Strip off leading blanks;
  WHILE s≠"." ∧ s≠"[" ∧ s≠NULL DO fnam10 ← fnam10 & LOP(s);  ! Build up file name;
  WHILE s≠"[" ∧ s≠NULL DO fext10 ← fext10 & LOP(s);	! Build up file extension;
  IF s="[" THEN ppn10 ← s;		! Set ppn if present;
  END;


PROCEDURE SENDBUFFER;
  BEGIN
  WHILE (bufadr←PEEK(bufptr))=0 DO CALL(0,"SLEEP");	 ! Sleep for 1 tick;
  IF bufadr LAND 1 THEN			! Something's wrong - abort;
    BEGIN
    PRINT("Error while writing file"&crlf);
    GO TO fin;
    END;
  bufadr ← bufadr + base;
  POKEARRAY(bufadr,256,outbuffer,0);	! Transfer the sector over;
  POKE(bufptr,0);			! Tell 11 to write it out;
  outptr ← 1;				! Reset output buffer pointer;
  END;


PROCEDURE FILLBUFFER;
  BEGIN
  INTEGER i,j,k,b1,b2,b3,b4,word1,word2;
  print (crlf,"[fillbuffer...]",crlf);
  FOR i:=1 STEP 2 UNTIL 255 DO begin
    k ← WORDIN(dskchan);              ! Get next 2 words from file;
    j ← POINT(8,k,7);
    b1←ldb(j); b2←ildb(j); b3←ildb(j); b4←ildb(j);	! retreive bytes;
    word1 ← b1 + (b2 LSH 8);          ! First word;
    word2 ← b3 + (b4 LSH 8);          ! Second word;
    inbuffer[i] ← word1;              ! Store 1st word;
    inbuffer[i+1] ← word2; 
    end;
  inptr ← 1;				! Reset in-buffer pointer;
  END;


INTEGER PROCEDURE NEXTWORD;
  BEGIN
  INTEGER I;
  IF INPTR>256 THEN FILLBUFFER;		! And reset INPTR to 1;
  I ← INBUFFER[INPTR];
  INPTR ← INPTR + 1;
! PRINT("[NextWord:",cvos(i),"]");
  RETURN (I);
  END;

PROCEDURE WRITEWORD (INTEGER W);
  BEGIN
! PRINT("[WriteWord(",w,") ]");
  OUTBUFFER[OUTPTR] ← W;
  OUTPTR ← OUTPTR + 1;
  IF OUTPTR>256 THEN SENDBUFFER;	! And reset outptr to 1;
  END;
! START HERE;

SETBREAK(1,crlf,NULL,"INS");

ALINIT(false);	! Assign the ELF, but don't care about ARM;

PRINT(crlf & "10-11 FTP Program"&crlf&crlf);
print ("** This version does object file conversions!! **",crlf);
chan ← GETCHAN;
OPEN(chan,"TTY53",0,1,1,999,brk,dum);
    QUICK_CODE
	LABEL XIT,SETUP;
	HRRI '13,SETUP;		    ! Command list to initialize the tty;
	HRLI '13,-3;		    ! Number of commands;
	TTYSET '13,0;		    ! Do it;
	JRST	XIT;
SETUP:
!	'072453000001;		! Set TTY EXIST;
!	'040453000005;		! Set tty speed = 1200 baud;
	'001453000004;		! Set (XON &) NO ECHO;
	'002453010000;		! Set TTY NO ARROW?;
	'023453000001;		! Set TTY GAG;
XIT:	END;

OUT(chan,"RUN OBJFTP/CKP=NO"&crlf);
WHILE INPUT(chan,1) = NULL DO ;		! Ignore echo from RSX;
WHILE (s←INPUT(chan,1)) = NULL ∨ s=">" DO ;
base ← CVO(s) LSH 6;			! Get address of Partition Base;
PRINT("Partition base = ",CVOS(base),crlf);
WHILE (s←INPUT(chan,1)) = NULL DO ;
bufptr ← CVO(s);			! Get address of buffer pointer;
PRINT("Buffer pointer = ",CVOS(bufptr),crlf);
bufptr ← base + bufptr;

dskchan ← GETCHAN;
OPEN(dskchan,"DSK",'10,19,0,0,0,eof);

WHILE TRUE DO		! Get file to ship over;
  BEGIN
  PRINT("*");
  f1 ← INCHWL;		! Read file name;
  IF f1 = NULL THEN
    BEGIN
    POKE(bufptr+4,0);	! Tell 11 we're finished;
    CALL(0,"EXIT");
    END;
  PARSE10(f1);
  LOOKUP(dskchan,fnam10 & fext10 & ppn10,i);
  IF i THEN
      BEGIN PRINT("ABORTED - Can't find:",fnam10,fext10,ppn10,crlf); GO TO fin END;
  POKE(bufptr+2,1);			! Tell 11 we're ready to start;

  eof ← FALSE;
  FillBuffer; 			! Fill 1st input buffer (128 words from 11);
  outptr ← 1;			! First location to fill in output buffer;
  DO BEGIN			! Start transferring characters to the 11;
    INTEGER bb1,bb2,len,jj,eor;
    j ← nextword;	    		! Figure out record length;
    bb1 ← (j LAND '377)-'60;		! Low byte, convert ascii to integer;
    bb2 ← ((j LSH -8) LAND '377)-'60;	! and high byte;
    if j = '57136 then begin		! End of record...ignore the rest;
!     print(crlf,"End of buffer. Words we ignore: ");
!     for jj←inptr TIL 256 do print(cvos(inbuffer[jj])," "); 
!     print(crlf);
      FillBuffer;			! So ignore the rest of this buffer;
      j ← NextWord;       		! Re-get 1st word;
      bb1 ← (j LAND '377)-'60;		! and re-do byte getting;
      bb2 ← ((j LSH -8) LAND '377)-'60;	
      end;
    len ← (bb1 * 10) + bb2;
    j ← nextword; 
    bb1 ← (j LAND '377)-'60;		! Low byte, convert ascii to integer;
    bb2 ← ((j LSH -8) LAND '377)-'60;	! and high byte;
    len ← (len * 100) + (bb1 * 10) + bb2;
!   print (crlf,"[ Length=",len,"] ",crlf);
    len ← len - 4;			! Account for offset;
    writeword (len);			! Write record length;
    len ← len DIV 2;     		! Bytes => words;
    for jj ← 1 TIL len do begin  	! Read rest of record;
      j ← nextword;      		! Get next word;
      writeword(j);        		! Store 1st word;
      end;
    END 
  UNTIL eof;

  IF outptr<=256 then sendbuffer;	! Send remaining words, if any;
  POKE(bufptr+2,0);			! Tell 11 we're all done;
fin:
  CLOSE(dskchan);
  END;

END;